import { ReactNode, useState } from "react";
import {
  DragDropContext,
  Draggable,
  DraggableLocation,
  DraggableProps,
  Droppable,
  DroppableProps,
  DropResult,
} from "react-beautiful-dnd";
import "./index.moudle.css";

interface dataType {
  id: string;
  context: string;
}

interface DroppableBoxProps extends Omit<DroppableProps, "children"> {
  children: ReactNode;
}

interface DraggableItemProps extends Omit<DraggableProps, "children"> {
  children: ReactNode;
  // data: dataType
}

const createData = (count: number, deep: number, fIndex?: number): any[] => {
  return new Array(count)
    .fill("item")
    .map((item, index): dataType | dataType[] => {
      if (!!deep) return createData(count, deep - 1, index);
      return {
        id: `${item}-${Math.random() * 100}`,
        context: `${fIndex}-context-${item}-${index}`,
      };
    });
};
const reorder = <T extends unknown>(
  list: T[],
  startIndex: number,
  endIndex: number
): T[] => {
  const newList = Array.from(list);
  const [remove] = newList.splice(startIndex, 1);
  newList.splice(endIndex, 0, remove);
  return newList;
};
const reorderCount = (
  data: any,
  source: DraggableLocation,
  destination: any
): any => {
  if (!data) return data;
  const cData = Array.from(data);
  const curren = [...data[+source.droppableId]];
  const next = [...data[+destination.droppableId]];
  if (source.droppableId == destination.droppableId) {
    const [remove] = curren.splice(source.index, 1);
    curren.splice(destination.index, 0, remove);
    cData[+source.droppableId] = curren;
    return cData;
  }
  const [remove] = curren.splice(source.index, 1);
  console.log("删除的-------", remove);
  next.splice(destination.index, 0, remove);
  cData[+source.droppableId] = curren;
  cData[+destination.droppableId] = next;
  return cData;
};

const DroppableBox = ({ children, ...props }: DroppableBoxProps) => {
  return (
    <Droppable {...props}>
      {(provided) => (
        <div ref={provided.innerRef} {...provided.droppableProps}>
          {children}
          {provided.placeholder}
        </div>
      )}
    </Droppable>
  );
};

const DraggableItem = ({
  children,
  draggableId,
  index,
}: DraggableItemProps) => {
  return (
    <Draggable draggableId={draggableId} index={index}>
      {(provided) => (
        <div
          ref={provided.innerRef}
          {...provided.draggableProps}
          {...provided.dragHandleProps}
        >
          {children}
        </div>
      )}
    </Draggable>
  );
};

export const TestReactBeautilfulDndBord = () => {
  const [list, setList] = useState(createData(5, 1));

  const onDragEnd = (res: DropResult) => {
    console.log("拖拽结束---", res);
    const { source, destination, type } = res;
    if (
      (source.droppableId == destination?.droppableId &&
        source.index == destination.index) ||
      !destination
    )
      return;
    if (type == "COLUMN" && destination)
      return setList((oldList) => reorderCount(oldList, source, destination));
    return setList((oldList) =>
      reorder(oldList, source.index, destination?.index || 0)
    );
  };
  return (
    <DragDropContext onDragEnd={onDragEnd}>
      <DroppableBox droppableId="BORD" type="BORD" direction="horizontal">
        <div className="container">
          {list.map((item, index) => {
            return (
              <DraggableItem
                draggableId={`box-${index}`}
                index={index}
                key={`box-${index}`}
              >
                <div className="box">
                  <DroppableBox
                    droppableId={`${index}`}
                    type="COLUMN"
                    direction="vertical"
                  >
                    {item.map((child: any, childIndex: number) => (
                      <DraggableItem
                        draggableId={`${index}-${child.id}`}
                        index={childIndex}
                        key={`${child.id}-${index}`}
                      >
                        <div className="item">{child.context}</div>
                      </DraggableItem>
                    ))}
                  </DroppableBox>
                </div>
              </DraggableItem>
            );
          })}
        </div>
      </DroppableBox>
    </DragDropContext>
  );
};
